package zhoug.common.utils;

import android.util.SparseArray;

import zhoug.common.interfaces.Equals;
import zhoug.common.interfaces.NameTransformer;
import zhoug.common.interfaces.StringConverter;
import zhoug.common.interfaces.TextFunction;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

import androidx.annotation.NonNull;

/**
 * 集合工具
 *
 * @Author 35574
 * @Date 2020/8/5
 * @Description
 */
public class CollectionUtils {

    /**
     * 非空
     *
     * @param collection
     * @return
     */
    public static boolean notEmpty(Collection<?> collection) {
        return collection != null && collection.size() > 0;
    }

    /**
     * 空
     *
     * @param collection
     * @return
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.size() == 0;
    }

    /**
     * 把source中的全部数据加入data中
     *
     * @param data
     * @param source
     * @param clearData 是否清空data中的数据后再加入
     * @param <T>
     */
    public static <T> void addAll(List<T> data, List<T> source, boolean clearData) {
        if (clearData) {
            data.clear();
        }
        if (source != null && source.size() > 0) {
            data.addAll(source);
        }
    }

    public static <T> void addAll(List<T> data, List<T> source) {
        addAll(data, source, false);
    }

    /**
     * 返回list大小
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> int size(List<T> list) {
        return list != null ? list.size() : 0;
    }


    /**
     * list集合转化成String
     *
     * @param list
     * @param split 分割线
     * @param <T>
     * @return
     */
    public static <T extends NameTransformer> String listToNames(List<T> list, String split) {
        if (list != null && list.size() > 0) {
            if (split == null) {
                split = "、";
            }
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < list.size(); i++) {
                builder.append(list.get(i).transformName());
                if (i < list.size() - 1) {
                    builder.append(split);
                }
            }
            return builder.toString();
        }
        return null;
    }

    public static <T extends NameTransformer> String listToNames(List<T> list) {
        return listToNames(list, null);
    }

    /**
     * @noinspection unchecked
     */
    public static <F, T> ArrayList<T> parseList(List<F> src, Class<T> clz) {
        if (src == null) {
            return null;
        }
        if (src.isEmpty()) {
            return new ArrayList<>();
        }
        ArrayList<T> result = new ArrayList<>();
        for (F item : src) {
            //a是b的父类或接口,或者a和b为同一个类或同一个接口
            if (!clz.isAssignableFrom(item.getClass())) {
                throw new ClassCastException(String.format(Locale.CANADA, "%s不能转化成%s", item.getClass(), clz));
            }
            result.add((T) item);
        }
        return result;
    }

    /**
     * obj安全的转化为List<T> 泛型检查
     *
     * @param obj
     * @param classOfT
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> castList(Object obj, Class<T> classOfT) {
        if (obj == null) return null;
        if (obj instanceof List<?>) {
            List<?> objList = (List<?>) obj;
            for (Object item : objList) {
                //a是b的父类或接口,或者a和b为同一个类或同一个接口
                if (!classOfT.isAssignableFrom(item.getClass())) {
                    throw new ClassCastException(String.format(Locale.CANADA, "%s不能转化成%s", item.getClass(), classOfT));
                }
            }
            return (List<T>) objList;
        }
        return null;
    }

    /**
     * obj安全的转化为ArrayList<T> 泛型检查
     *
     * @param obj
     * @param classOfT
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> ArrayList<T> castArrayList(Object obj, Class<T> classOfT) {
        if (obj == null) return null;
        if (obj instanceof ArrayList<?>) {
            ArrayList<?> objList = (ArrayList<?>) obj;
            for (Object item : objList) {
                //a是b的父类或接口,或者a和b为同一个类或同一个接口
                if (!classOfT.isAssignableFrom(item.getClass())) {
                    throw new ClassCastException(String.format(Locale.CANADA, "%s不能转化成%s", item.getClass(), classOfT));
                }
            }
            return (ArrayList<T>) objList;
        }
        return null;
    }

    /**
     * obj安全的转化为SparseArray<T> 泛型检查
     *
     * @param obj
     * @param classOfT
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> SparseArray<T> castSparseArray(Object obj, Class<T> classOfT) {
        if (obj == null) return null;
        if (obj instanceof SparseArray<?>) {
            SparseArray<?> array = (SparseArray<?>) obj;
            for (int i = 0; i < array.size(); i++) {
                Object item = array.valueAt(i);
                //a是b的父类或接口,或者a和b为同一个类或同一个接口
                if (!classOfT.isAssignableFrom(item.getClass())) {
                    throw new ClassCastException(String.format(Locale.CANADA, "%s不能转化成%s", item.getClass(), classOfT));
                }
            }
            return (SparseArray<T>) array;
        }
        return null;
    }

    /**
     * 从原集合中复制指定条数的数据到新集合
     *
     * @param src       原集合
     * @param copyCount 需要复制的数量
     * @param repeat    需要复制的数量大于原集合的数量时是否从头开始循环取值知道达到指定数量
     * @param <T>
     * @return
     */
    public static <T> List<T> copyList(@NonNull List<T> src, int copyCount, boolean repeat) {
        if (src.size() > 0 && copyCount > 0) {
            int srcSize = src.size();
            int count = copyCount;
            if (!repeat) {
                count = Math.min(copyCount, srcSize);
            }
            List<T> result = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                result.add(src.get(i % srcSize));
            }
            return result;
        }
        return null;
    }

    /**
     * 从原集合中复制指定条数的数据到新集合
     *
     * @param src       原集合
     * @param copyCount 需要复制的数量
     * @param <T>
     * @return
     */
    public static <T> List<T> copyList(@NonNull List<T> src, int copyCount) {
        return copyList(src, copyCount, false);
    }

    public static <T> ArrayList<String> listToStringList(List<T> src, TextFunction<T> function) {
        if (src != null) {
            ArrayList<String> result = new ArrayList<>();
            for (int i = 0; i < src.size(); i++) {
                T t = src.get(i);
                if (function != null) {
                    result.add(function.getText(t));
                } else {
                    result.add(t != null ? t.toString() : null);
                }
            }
            return result;
        }
        return null;
    }


    /**
     * 判断给定的2个集合中的数据完全一样
     *
     * @param list1 集合1
     * @param list2 集合2
     * @return 是否一样
     */
    public static boolean equals(List<Object> list1, List<Object> list2) {

        return false;
    }

    /**
     * 去重
     *
     * @param list
     * @return
     */
    public static List<String> delRepeat(List<String> list) {
        List<String> collect;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            collect = list.stream().distinct().collect(Collectors.toList());
        } else {
            collect = new ArrayList<>(new LinkedHashSet<>(list));
        }
        return collect;
    }

    /**
     * 去重
     *
     * @param list
     * @param equals
     * @param <T>
     * @return
     */
    public static <T> List<T> delRepeat(List<T> list, Equals<T> equals) {
        if (list == null || list.size() <= 1) return list;
        List<T> result = new ArrayList<>();
        for (T item : list) {
            if (result.isEmpty()) {
                result.add(item);
            } else {
                boolean find = false;
                for (T addedItem : result) {
                    if (equals.equals(item, addedItem)) {
                        find = true;
                        break;
                    }
                }
                if (!find) {
                    result.add(item);
                }
            }
        }
        return result;
    }

    /**
     * list转化为string
     *
     * @param list      数据集合
     * @param converter 转换器 负责把对象转换成字符串
     * @param <T>       泛型
     * @return String字符串 ["str1","str2"]
     */
    public static <T> String listToString(List<T> list, @NonNull StringConverter<T> converter) {
        if (list == null) return null;
        if (list.isEmpty()) return "[]";
        StringBuilder builder = new StringBuilder();
        builder.append("[");
        int index = 0;
        int max = list.size() - 1;
        for (T item : list) {
            String s = converter.converterString(item);
            builder.append(s);
            if (index < max) {
                builder.append(",");
            }
            index++;
        }
        builder.append("]");
        return builder.toString();
    }

    /**
     * list转化为string
     * @param list 数据集合
     * @return String字符串 ["str1","str2"]
     * @param <T> 泛型
     */
    public static <T> String listToString(List<T> list) {
        return listToString(list, t -> t != null ? t.toString() : null);
    }


    /**
     * list转化为string
     *
     * @param list      数据集合
     * @param converter 转换器 负责把对象转换成字符串
     * @param <T>       泛型
     * @return String字符串 ["str1","str2"]
     */
    public static <T> String listToString(T[] list, @NonNull StringConverter<T> converter) {
        if (list == null) return null;
        if (list.length==0) return "[]";
        StringBuilder builder = new StringBuilder();
        builder.append("[");
        int index = 0;
        int max = list.length - 1;
        for (T item : list) {
            String s = converter.converterString(item);
            builder.append(s);
            if (index < max) {
                builder.append(",");
            }
            index++;
        }
        builder.append("]");
        return builder.toString();
    }
    /**
     * list转化为string
     * @param list 数据集合
     * @return String字符串 ["str1","str2"]
     * @param <T> 泛型
     */
    public static <T> String listToString(T[] list) {
        return listToString(list, t -> t != null ? t.toString() : null);
    }

}
